package org.gruposp2p.dnie.client.ui.dialogs;

import java.util.Date;
import java.util.List;
import org.gruposp2p.dnie.client.dto.DocumentToSignDTO;
import org.gruposp2p.dnie.client.dto.DocumentToSignOptionDTO;
import org.gruposp2p.dnie.client.event.EventBusManager;
import org.gruposp2p.dnie.client.event.OptionChangeEvent;
import org.gruposp2p.dnie.client.event.OptionChangeHandler;
import org.gruposp2p.dnie.client.event.DocumentToSignChangeEvent;
import org.gruposp2p.dnie.client.json.DTOToJSON;
import org.gruposp2p.dnie.client.json.JSONToDTO;
import org.gruposp2p.dnie.client.server.ServerFacade;
import org.gruposp2p.dnie.client.server.StatusData;
import org.gruposp2p.dnie.client.ui.panel.MainPanel;
import org.gruposp2p.dnie.client.ui.widget.GlassedDialog;
import org.gruposp2p.dnie.client.util.URLConstants;
import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.Response;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import com.google.gwt.user.datepicker.client.DateBox;

public class DocumentToSignDialog extends DialogBox implements OptionChangeHandler {

    private DocumentToSignDTO signatureDataDTO;
    private TextBox titleTextBox;
    private TextArea contentTextArea;
    private boolean isDialogWithOptions = false;
    private int dialogType;
    private DateBox dateBeginBox = new DateBox();
    private DateBox dateEndBox = new DateBox();
    private final ServerRequestCallback requestCallback = new ServerRequestCallback();

    public DocumentToSignDialog (DocumentToSignDTO signatureDataDTO) {
        if (DocumentToSignDTO.DOCUMENT_TYPE_MANIFEST.equals(
                signatureDataDTO.type)) {
            setText(MainPanel.constants.SignatureDataDialogManifestCaption());
            isDialogWithOptions = false;
        }
        else if(DocumentToSignDTO.DOCUMENT_TYPE_VOTE.equals(
                signatureDataDTO.type)) {
            setText(MainPanel.constants.SignatureDataDialogVoteCaption());
            isDialogWithOptions = true;
        }
        this.signatureDataDTO = signatureDataDTO;
        showDialog(dialogType, signatureDataDTO);
        ensureDebugId("SignatureDataDialog");
        EventBusManager.getInstance().registerToVotingOptionChange(this);
    }

    private void showDialog (
            int dialogType, DocumentToSignDTO signatureDataDTO) {
        this.dialogType = dialogType;
        FlexTable layout = new FlexTable();
        CellFormatter cellFormatter = layout.getCellFormatter();
        layout.clear();
        layout.setCellSpacing(6);
        int widgetRow = 0;
        layout.setHTML(widgetRow++, 0,
            MainPanel.constants.SignatureDataDialogTitleLabel());
        titleTextBox = new TextBox ();
        titleTextBox.setWidth("350");
        titleTextBox.setText(signatureDataDTO.title);
        layout.setWidget(widgetRow++, 0, titleTextBox);
        layout.setHTML(widgetRow++, 0,
        		MainPanel.constants.SignatureDataDialogContentLabel());
        contentTextArea = new TextArea();
        contentTextArea.setWidth("400");
        contentTextArea.setHeight("180");
        contentTextArea.setText(signatureDataDTO.content);
        layout.setWidget(widgetRow++, 0, contentTextArea);
        layout.setWidget(widgetRow++, 0, getDatePanel(dialogType,
            signatureDataDTO.dateBegin, MainPanel.constants.dateBegin(), dateBeginBox));
        layout.setWidget(widgetRow++, 0, getDatePanel(dialogType,
                signatureDataDTO.dateEnd, MainPanel.constants.dateEnd(), dateEndBox));
        if (isDialogWithOptions)
            layout.setWidget(widgetRow++, 0, getVotingOptionsPanel(
                signatureDataDTO.options));
        layout.setWidget(widgetRow, 0, getButtonPanel());
        cellFormatter.setHorizontalAlignment(widgetRow, 0, HorizontalPanel.ALIGN_RIGHT);
        setWidget(layout);
        //To solve Firefox strange effect
        titleTextBox.setFocus(true);
    }

    private String validateData () {
        String result = null;
        if (!"".equals(titleTextBox.getText().trim()) &&
                !"".equals(contentTextArea.getText().trim()) &&
                dateBeginBox.getValue() != null &&
                dateEndBox.getValue() != null) {
        	if (signatureDataDTO.type.equals(DocumentToSignDTO.DOCUMENT_TYPE_MANIFEST)
        			|| (signatureDataDTO.type.equals(DocumentToSignDTO.DOCUMENT_TYPE_VOTE)
        					&& signatureDataDTO.options.size() > 0)) {
                signatureDataDTO.content = contentTextArea.getText();
                signatureDataDTO.dateBegin = dateBeginBox.getValue();
                signatureDataDTO.dateEnd = dateEndBox.getValue();
                signatureDataDTO.title = titleTextBox.getText();
                signatureDataDTO.url = URLConstants.getDocumentToSignBaseUrl();
                signatureDataDTO.optionSelectionType = DocumentToSignDTO.OPTION_TYPE_EXCLUSIVE;
                JSONObject jsonObject = DTOToJSON.getDocumentToSignJSON(signatureDataDTO);
                result = jsonObject.toString();	
        	} else showValidationErrorDialogBox();
        } else {
        	showValidationErrorDialogBox();
        }
        return result;
    }

    private void showValidationErrorDialogBox () {
        ValidationErrorDialogBox validationErrorDialogBox =
            new ValidationErrorDialogBox();
        validationErrorDialogBox.show();
    }
    
    private ScrollPanel getVotingOptionsPanel (
    		List<DocumentToSignOptionDTO> options) {
        final VerticalPanel verticalPanel = new VerticalPanel();
        FlexTable layout = new FlexTable();
        layout.setCellSpacing(6);
        layout.clear();
        FlexCellFormatter cellFormatter = layout.getFlexCellFormatter();
        AbsolutePanel headerPanel = new AbsolutePanel();
        headerPanel.setSize("325px", "35px");
        headerPanel.add(new HTML(MainPanel.constants.votingOptionPanelCaption()), 10, 0);
        Button newOptionButton = new Button(
                    MainPanel.constants.votingOptionButtonCaption(),
            new ClickHandler() {
              public void onClick(ClickEvent event) {
                        DocumentToSignOptionDTO option = new DocumentToSignOptionDTO();
                        CreateOptionDialog createOptionDialog =
                            new CreateOptionDialog(option);
                        createOptionDialog.setAnimationEnabled(true);
                        createOptionDialog.showRelativeTo(verticalPanel);;
              }
            });
        headerPanel.add(newOptionButton, 220, 0);
        layout.setWidget(0, 0, headerPanel);
        int optionRow = 1;
            for (DocumentToSignOptionDTO option : options) {
                  layout.setWidget(optionRow++, 0,
                              getVotingOptionPanel(dialogType, option));
            }
            verticalPanel.add(layout);
            verticalPanel.setWidth("100%");
            //verticalPanel.setStyleName("dnie-inner-panel");
        ScrollPanel scroller = new ScrollPanel(verticalPanel);
        scroller.setSize("400px", "150px");
        scroller.setStyleName("dnie-inner-panel");
        return scroller;
    }

    private HorizontalPanel getVotingOptionPanel (int dialogType,
                    final DocumentToSignOptionDTO option) {
        final HorizontalPanel horizontalPanel = new HorizontalPanel();
        horizontalPanel.setSpacing(6);
        TextBox optionText = new TextBox();
        optionText.setReadOnly(true);
        optionText.setText(option.content);
        optionText.setWidth("240");
        horizontalPanel.add(optionText);
        Button deleteOptionButton = new Button(
                MainPanel.constants.deleteCaption(),
        new ClickHandler() {
          public void onClick(ClickEvent event) {
                    ConfirmDeleteOptionDialog deleteOptionDialog =
                        new ConfirmDeleteOptionDialog(option);
                    deleteOptionDialog.showRelativeTo(horizontalPanel);
          }
        });
        horizontalPanel.add(deleteOptionButton);
        return horizontalPanel;
    }

    private HorizontalPanel getButtonPanel () {
        HorizontalPanel buttonPanel = new HorizontalPanel();
        buttonPanel.setSpacing(5);
        Button cancelButton = new Button(
                MainPanel.constants.cancelButtonText(),
                new ClickHandler() {
                public void onClick(ClickEvent event) {
                    hide();
                }
                });
            Button acceptButton = new Button(
                MainPanel.constants.acceptButtonText(),
                new ClickHandler() {
                public void onClick(ClickEvent event) {
                    String postData = validateData();
                    if (postData != null){
                    	if (signatureDataDTO.id == null ||
                    			"".equals(signatureDataDTO.id)) {
                            ServerFacade.doPost(
                                    URLConstants.getUserDocumentsToSignPostUrl(),
                                    postData, requestCallback);
                    	} else {
                            ServerFacade.doPost(
                                    URLConstants.getDocumentToSignUrl(signatureDataDTO.id),
                                    postData, requestCallback);                    		
                    	}
                      hide();
                    }
                }
                });
            buttonPanel.add(acceptButton);
            buttonPanel.add(cancelButton);
        return buttonPanel;
    }

    private VerticalPanel getDatePanel (
            int dialogType, Date date, String dateBoxCaption, DateBox dateBox) {
        VerticalPanel datePanel = new VerticalPanel();
        datePanel.setSpacing(5);
        datePanel.setWidth("250px");
        datePanel.add(new HTML(dateBoxCaption));
        dateBox.setValue(date);
        datePanel.add(dateBox);
        return datePanel;
    }

    @Override
    public void processOption(OptionChangeEvent event) {
        DocumentToSignOptionDTO option = event.option;
        List<DocumentToSignOptionDTO> options = signatureDataDTO.options;
        signatureDataDTO.title = titleTextBox.getText();
        signatureDataDTO.content = contentTextArea.getText();
        signatureDataDTO.dateBegin = dateBeginBox.getValue();
        signatureDataDTO.dateEnd = dateEndBox.getValue();
        boolean isAdded = true;
        boolean isDeleted = false;
        for (DocumentToSignOptionDTO option1: options) {
            if (option.equals(option1)) {
                isAdded = false;
                if(event.eventType == OptionChangeEvent.OPTION_EDITED) {
                    option1.content = option.content;
                } else {
                    isDeleted = true;
                }
            }
        }
        if (isAdded) options.add(option);
        if (isDeleted){
            options.remove(option);
        }
        showDialog(dialogType, signatureDataDTO);
    }

    private class ServerRequestCallback implements RequestCallback {

        @Override
        public void onError(Request request, Throwable exception) {
            StatusData status = new StatusData();
            status.description = exception.getMessage();
            GlassedDialog.getInstance().showErrorGettingResource(status);
        }

        @Override
        public void onResponseReceived(Request request, Response response) {
            JSONValue jsonValue = JSONParser.parse(response.getText());
            DocumentToSignDTO signatureData = JSONToDTO.getDocumentToSignDTO(jsonValue);
            DocumentToSignChangeEvent signatureDataChangeEvent =
                    new DocumentToSignChangeEvent(signatureData, DocumentToSignChangeEvent.ADDED);
            EventBusManager.getInstance().fireEvent(signatureDataChangeEvent);
        }

    }

}